<template>
  <div class="login-container" :style="{ backgroundImage: `url(${bgsPath})` }">
    <div class="login-container-form">
      <div class="login-container-hello">欢迎登录</div>
      <div class="login-container-title">家庭医生</div>
      <a-form ref="formRef" :model="form" :rules="rules" @keyup.enter="handleSubmit">
        <a-form-item name="username">
          <a-input v-model:value="form.username" autocomplete="off" placeholder="请输入用户名">
            <template v-slot:prefix>
              <UserOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item name="password">
          <a-input-password v-model:value="form.password" autocomplete="off" placeholder="请输入密码">
            <template v-slot:prefix>
              <LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item>
          <a-button type="primary" :loading="isLoading" size="large" block @click="handleSubmit()">
            立即登录
          </a-button>
        </a-form-item>
        <a-form-item>
          <a-button style="margin-top: 10px" type="primary" size="large" block @click="facelogin()">
            人脸验证登录
          </a-button>
        </a-form-item>
        <a-form-item>
          <a-row>
            <a-col :span="1">
              <a-button type="link" size="large" block @click="$router.replace('/register')">
                注册
              </a-button>
            </a-col>
          </a-row>
        </a-form-item>
      </a-form>
    </div>
  </div>
  <!-- 人脸识别对话框 -->
  <a-modal width="398px" v-model:visible="faceDialogVisible" @cancel="isLoading = false" :footer="null">
    <div class="faceTitle">人脸验证</div>
    <video ref="video" height="350" width="350" autoplay style="margin: 0 auto" v-show="!showCanvas"></video>
    <canvas ref="canvas" height="350" width="350" style="margin: 0 auto" v-show="showCanvas"></canvas>
    <a-button type="primary" style="width: 100%; height: 40px; margin-top: 15px" @click="takePhoto"
      v-show="!showCanvas">拍照</a-button>
    <a-row v-show="showCanvas" :gutter="20" style="margin-top: 15px">
      <a-col :span="11" :offset="1">
        <a-button style="width: 100%; height: 40px" type="info" @click="showCanvas = false">重拍</a-button>
      </a-col>
      <a-col :span="11">
        <a-button type="primary" :loading="faceLoading" style="width: 100%; height: 40px" @click="upload">验证</a-button>
      </a-col>
    </a-row>
  </a-modal>
  <!-- 人脸验证登录对话框 -->
  <a-modal width="398px" v-model:visible="faceloginVisible" :footer="null">
    <div class="faceTitle">人脸验证登录</div>
    <video ref="video1" height="350" width="350" autoplay style="margin: 0 auto" v-show="!showfaceCanvas"></video>
    <canvas ref="canvas1" height="350" width="350" style="margin: 0 auto" v-show="showfaceCanvas"></canvas>
    <a-button type="primary" style="width: 100%; height: 40px; margin-top: 15px" @click="takePhoto1"
      v-show="!showfaceCanvas">拍照</a-button>
    <a-row v-show="showfaceCanvas" :gutter="20" style="margin-top: 15px">
      <a-col :span="11" :offset="1">
        <a-button style="width: 100%; height: 40px" type="info" @click="showfaceCanvas = false">重拍</a-button>
      </a-col>
      <a-col :span="11">
        <a-button type="primary" style="width: 100%; height: 40px" @click="faceupload">验证</a-button>
      </a-col>
    </a-row>
  </a-modal>
  <!-- //一张人脸可能有多个账号 匹配人脸之后选择要登录的账号 -->
  <a-modal width="450px" v-model:visible="showselect" :footer="null">
    <div class="faceTitle">请选择你要登录的账号</div>
    <a-radio-group v-model:value="faceloginid">
      <a-radio :style="{
        display: 'block',
        height: '30px',
        lineHeight: '30px',
      }" :value="item.id" v-for="item in faceuser" :key="item.id">{{ item.username }}</a-radio>
    </a-radio-group>
    <a-row :gutter="20" style="margin-top: 15px">
      <a-col :span="11" :offset="1">
        <a-button style="width: 100%; height: 40px" type="info" @click="showselect = false">取消</a-button>
      </a-col>
      <a-col :span="11">
        <a-button type="primary" style="width: 100%; height: 40px" :disabled="!faceloginid"
          @click="submitFaceLogin">确定</a-button>
      </a-col>
    </a-row>
  </a-modal>
</template>

<script lang="ts" setup>
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { message } from "ant-design-vue";
import { getCurrentInstance, reactive, ref, UnwrapRef } from "vue";
import { UserOutlined, LockOutlined } from "@ant-design/icons-vue";
import storage from "store";
import request from "@/request";

const { proxy }: any = getCurrentInstance();

// 表单数据
const form = data_form();

const rules = reactive({
  username: [
    {
      required: true,
      message: "请输入用户名",
      trigger: "change",
    },
  ],
  password: [
    {
      required: true,
      message: "请输入密码",
      trigger: "change",
    },
  ],
});

const formRef = ref();

const store = useStore();

const router = useRouter();

// 用户数据
const userData: any = ref({});

// 登录成功跳转页面
const successJump = () => {
  storage.set("token", userData.value.token);
  storage.set("_id", userData.value._id);
  store.commit("user/setToken", userData.value.token);
  isLoading.value = false;
  const route = router.currentRoute.value;
  const url = route.query.redirect || "/";
  message.success("登录成功!");
  closeMedia();
  router.push(url as string);
};

/**
 * @desc: 免人脸登录提交
 */


/**
 * @desc: 登录提交
 */
const handleSubmit = (): void => {
  formRef.value.validate().then(() => {
    isLoading.value = true;
    store
      .dispatch("user/login", form)
      .then((e) => {
        console.log(e);
        
        userData.value = e;
        showFaceDialog();
        // successJump(e)
      })
      .catch((err) => {
        isLoading.value = false;
        message.error(err.message || err.data.message);
      });
  });
};

// 背景图片列表
const bgsPath = ref(
  "/images/login/bg.png"
);
// 登录按钮的loading状态
const isLoading = ref(false);
// 表单数据
function data_form() {
  const form: UnwrapRef<any> = reactive({
    username: undefined,
    password: undefined,
  });
  return form;
}

// 录入人脸对话框的显示隐藏
const faceDialogVisible = ref(false);
// 摄像头对象
const mediaTracks = ref();
const mediaTracks1 = ref();
// canvas显示隐藏
const showCanvas = ref(false);
// 显示人脸对话框
async function showFaceDialog() {
  faceDialogVisible.value = true;
  // 等待dom结点渲染完成
  await proxy.$nextTick();
  const constraints = {
    video: { width: 500, height: 500 },
    // audio: true,  // 麦克风
  };
  // 获得video摄像头区域
  const video = proxy.$refs.video;
  const promise = navigator.mediaDevices.getUserMedia(constraints);
  promise
    .then((MediaStream) => {
      
      
      video.srcObject = MediaStream;
      console.log(123,video.srcObject);
      
      // 保存stop关闭摄像头的方法
      mediaTracks.value =
        typeof (MediaStream as any).stop === "function"
          ? MediaStream
          : MediaStream.getTracks()[0];
      video.play();
    })
    .catch((e) => {
      faceDialogVisible.value = false;
      isLoading.value = false;
      message.error("获取摄像头权限失败!");
    });
}
// 拍照
function takePhoto() {
  // 获得Canvas对象
  const video = proxy.$refs.video;
  const canvas = proxy.$refs.canvas;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(video, 0, 0, 350, 350);
  showCanvas.value = true;
}
function takePhoto1() {
  // 获得Canvas对象
  const video = proxy.$refs.video1;
  const canvas = proxy.$refs.canvas1;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(video, 0, 0, 350, 350);
  showfaceCanvas.value = true;
}
// 关闭摄像头
function closeMedia() {
  mediaTracks.value && mediaTracks.value.stop();
  mediaTracks1.value && mediaTracks1.value.stop();
}
// 人脸验证按钮loading
const faceLoading = ref(false);
// 人脸验证
async function upload() {
  faceLoading.value = true;
  const canvas = proxy.$refs.canvas;
  const base64 = canvas.toDataURL().slice(22);
  const { data } = await request
    .post("/login/face/" + userData.value._id, { base64 })
    .catch((e) => e);
    console.log(`验证`, data);
  if (data.code !== 200) {
    faceLoading.value = false;
    return message.error(data.message);
  }
  successJump();
}
// 控制人脸验证登录显示
const faceloginVisible = ref(false);
const showfaceCanvas = ref(false);
// 人脸验证登录功能
const facelogin = async () => {
  faceloginVisible.value = true;
  // 等待dom结点渲染完成
  await proxy.$nextTick();
  const constraints = {
    video: { width: 500, height: 500 },
    // audio: true,  // 麦克风
  };
  // 获得video摄像头区域
  const video = proxy.$refs.video1;
  const promise = navigator.mediaDevices.getUserMedia(constraints);
  promise
    .then((MediaStream) => {
      video.srcObject = MediaStream;
      // 保存stop关闭摄像头的方法
      mediaTracks1.value =
        typeof (MediaStream as any).stop === "function"
          ? MediaStream
          : MediaStream.getTracks()[0];
      video.play();
    })
    .catch((e) => {
      faceloginVisible.value = false;
      message.error("获取摄像头权限失败!");
    });
};
// 人脸验证成功的用户数据
const faceuser: any = ref([]);
// 人脸验证
async function faceupload() {
  const canvas = proxy.$refs.canvas1;
  const base64 = canvas.toDataURL().slice(22);
  const { data } = await request.post("/facelogin", { base64 });
  if (data.users.length === 0) {
    return message.error("未匹配到对应人脸信息,请重新尝试或使用其他方式登录!");
  }
  faceuser.value = data.users;
  faceloginVisible.value = false;
  message.success("人脸信息匹配成功!");
  showselect.value = true;
}
// 控制选择账号显示
const showselect = ref(false);
const faceloginid = ref();
// 直接进行人脸登录
const submitFaceLogin = async () => {
  const { data } = await request.post("/submitfacelogin", {
    id: faceloginid.value,
  });
  userData.value = data;
  successJump();
};
</script>
<style lang="scss" scoped>
.faceTitle {
  font-size: 20px;
  margin-top: -10px;
  margin-bottom: 10px;
}

video,
img,
canvas {
  transform: scaleX(-1);
}

.login-container {
  width: 100vw;
  height: 100vh;
  background-size: 100% 100%;

  .login-container-form {
    position: absolute;
    left: 75%;
    top: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    width: 540px;
    max-width: 100%;
    padding: 40px 70px;
    overflow: hidden;
    background-color: #fff;
    border-radius: 5px;
    -webkit-box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%);
    box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%);
    text-align: center;

    .login-container-hello {
      font-size: 26px;
      line-height: 1;
      color: #333;
      margin-bottom: 10px;
    }

    .login-container-title {
      font-size: 14px;
      line-height: 1;
      color: #999;
      margin-bottom: 26px;
    }

    ::v-deep .ant-form-item {
      margin-bottom: 0;

      .ant-form-item-explain {
        margin-top: -24px;
        text-align: left;
      }

      .ant-input-affix-wrapper {
        margin-bottom: 25px;
        border: 1px solid #dcdfe6;
        border-radius: 5px;
        color: #454545;
        -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
        transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
        height: 50px;

        .ant-input {
          padding-left: 10px;
        }
      }
    }

    .ant-btn-lg {
      height: 48px;
      border-radius: 5px;
    }
  }
}
</style>